﻿
Public Class ClsCommunicate

#Region "変数宣言"
    Public pop3Client As New OpenPop.Pop3.Pop3Client
    Private clsOpenSSL As New OpenSllNet
    Private strMymailaddr As String = ""
    'メールボックスのメール件数を保存
    Private indexMailHeader As OpenPop.Mime.Header.MessageHeader
    Private indexXY() As Integer = Nothing
    Private indexSystemName As String = Nothing
    Private newMailInfo() As CommStruct = Nothing

    '受信フラグをセット（-1：何もしない（初期時））
    Private flgReceipt As Integer = -1
    '最終送信時間＝2000/1/1 0:0:0
    Private lastSendTime As DateTime = DateTime.Parse("2000/1/1 0:0:0")
    Private Const CST_Colon As String = ":"
    Private Const CST_Equal As String = "="
    Public cntMail As Integer = 0

    Private Structure path
        Friend Shared settings As String
        Friend Shared settings_uid As String
        Friend Shared openSslKey As String
        Friend Shared csv As String
    End Structure
    Private Structure settings
        Friend Shared PopSsl As Boolean
        Friend Shared SmtpSsl As Boolean
        Friend Shared Interval As Integer
        Friend Shared PopPort As Integer
        Friend Shared SmtpPort As Integer
        Friend Shared RetryCount As Integer
        Friend Shared RetryTime As Integer
        Friend Shared SendMailInterval As Integer
        Friend Shared TimeDifference As Integer
    End Structure

#End Region

#Region "リトライ項目定義"

    '暗号化キー{0}が設定ファイルに存在しない時、イベントログ出力記録を保存
    Private lstErrData As New List(Of String)

    Private Structure RetryItems
        Friend Shared connect As New CommStruct("connect", 0)
        Friend Shared login As New CommStruct("login", 0)
        Friend Shared receiptMail As New CommStruct("receiptMail", 0)
        Friend Shared receiptMailCount As New CommStruct("receiptMailCount", 0)
        Friend Shared receiptMailDomainCount As New CommStruct("receiptMailDomainCount", 0)
        Friend Shared sendMailToMyself As New CommStruct("sendMailToMyself", 0)
        Friend Shared sendMail() As CommStruct
        Friend Shared deleMail As New CommStruct("deleMail", 0)
    End Structure
    Private Structure CommStruct
        Friend name As String
        Friend num As Integer
        Friend isErrObj As Boolean
        Friend Sub New(ByVal name As String, ByVal num As Integer, Optional ByVal isErrObj As Boolean = False)
            Me.name = name
            Me.num = num
            Me.isErrObj = isErrObj
        End Sub
    End Structure

#End Region

#Region "メール編集項目定義"
    Private Structure mailItems
        Friend outputLevel As Integer
        Friend oldItem As String
        Friend newItem As String
        Friend value As String

        ''' <summary>
        ''' メール項目
        ''' </summary>
        ''' <remarks>outputLevel：出力区分（1:送信対象＆CSV出力内容、2：CSV出力内容）</remarks>
        Friend Sub New(ByVal outputLevel As Integer, ByVal oldItem As String, ByVal newItem As String, _
                       Optional ByVal value As String = Nothing)
            Me.outputLevel = outputLevel
            Me.oldItem = oldItem
            Me.newItem = newItem
            Me.value = value
        End Sub
    End Structure

    Private Structure MailItemValue
        Friend Shared resultDecrypt As Integer
        Friend Shared mailItems() As mailItems
        Friend Shared titleName As String
        Friend Shared body As String
    End Structure

    ''' <summary>
    ''' メール項目リスト
    ''' </summary>
    ''' <remarks></remarks>
    Private mailItemList() As mailItems = New mailItems(16) {
            New mailItems(1, "Feed item type: Pinpoint malware detected machine", "Feed 種別: Pinpointがマルウェアを検出しました"), _
            New mailItems(1, "Event received at", "発生時刻"), _
            New mailItems(1, "Trusteer security event ID", "セキュリティイベント ID"), _
            New mailItems(1, "User IP address", "IPアドレス"), _
            New mailItems(1, "Country name", "国名"), _
            New mailItems(1, "City name", "都市名"), _
            New mailItems(1, "Organization", "組織名"), _
            New mailItems(1, "Application", "アプリケーション"), _
            New mailItems(1, "Detected at", "検出URL"), _
            New mailItems(1, "Malware", "マルウェア名"), _
            New mailItems(1, "Trusteer malware data", "Trusteerマルウェアデータ"), _
            New mailItems(1, "Malware group", "マルウェアグループ"), _
            New mailItems(1, "User agent string", "ユーザーエージェント"), _
            New mailItems(1, "Code", "コード"), _
            New mailItems(1, "User data", "ユーザーID"), _
            New mailItems(0, "data", "暗号化データ"), _
            New mailItems(2, "key_id", "暗号化キー") _
        }
#End Region

#Region "初期化処理"

    ''' <summary>
    ''' サービス開始する時の初期化処理
    ''' </summary>
    Public Function init() As Boolean

        Dim hDirInfoBar As System.IO.DirectoryInfo
        Dim strRootDir As String

        Try

            'StreamReader の新しいインスタンスを生成する
            hDirInfoBar = New System.IO.DirectoryInfo(My.Application.Info.DirectoryPath)

            '構成フォルダを設定
            strRootDir = hDirInfoBar.Parent.FullName & "\"

            '設定ファイルの格納場所を設定
            path.settings = strRootDir & ClsStatic.INFO_PATH.SETTINGS
            'UIDファイルの格納場所を設定
            path.settings_uid = strRootDir & ClsStatic.INFO_PATH.SETTINGS_UID

            '■エラーログの格納場所をデフォルト設定（設定ファイルの「出力パス」を取得する前、又は取得できない場合用）
            SystemError.FolderPath = strRootDir & ClsStatic.INFO_PATH.LOG

            '■設定ファイルの存在するか確認
            If Not System.IO.File.Exists(path.settings) Then
                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_FILE_NOTEXIST, ClsStatic.EventID.Err)
                Return False
            End If

            '■XMLファイルから設定を読み込む
            If InitSettings.LoadFromXmlFile(path.settings) = False Then
                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_READ_ERR, ClsStatic.EventID.Err)
                Return False
            End If
            '▲UIDファイルが存在する場合
            If System.IO.File.Exists(path.settings_uid) Then
                If UidSettings.LoadFromXmlFile(path.settings_uid) = False Then
                    WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_READ_UID_ERR, ClsStatic.EventID.Err)
                    Return False
                Else
                    'Uidファイル更新状態の初期化
                    UidSettings.isChanged = False
                End If
            End If

            '■設定ファイルの内容の整合性チェック
            If Me.checkConfig() = False Then
                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_CHECK_ERR, ClsStatic.EventID.Err)
                Return False
            End If

            '↓ UPD AT 2014/01/23 BY SHIN (仕様変更：パスフレーズ暗号化追加)
            ''■設定ファイルのパスワードのセキュリティ処理
            'If onSecurityForPasswordByUserId() = False Then
            '    Return False
            'End If
            '■設定ファイルの項目をチェックし、暗号化して保存する
            If encryptByUserId() = False Then
                Return False
            End If
            '■設定ファイルの項目を復号化する
            If decryptByUserId() = False Then
                Return False
            End If
            '↑ UPD AT 2014/01/23 BY SHIN (仕様変更：パスフレーズ暗号化追加)

            '■復号化キーの格納場所を設定
            path.openSslKey = InitSettings.Instance.PrivateKeyPath.Trim
            If Right(path.openSslKey, 1) <> "\" Then path.openSslKey &= "\"


            Dim outputPath As String = InitSettings.Instance.OutputPath.Trim
            If Right(outputPath, 1) <> "\" Then outputPath &= "\"

            '■CSVファイルの格納場所を設定
            path.csv = outputPath & ClsStatic.INFO_PATH.CSV
            'フォルダを作成
            If createDirectory(path.csv) = False Then
                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_CHECK_ERR, ClsStatic.EventID.Err)
                Return False
            End If

            '■ログの格納場所を設定
            SystemError.FolderPath = outputPath & ClsStatic.INFO_PATH.LOG
            'フォルダを作成
            If createDirectory(SystemError.FolderPath) = False Then
                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_CHECK_ERR, ClsStatic.EventID.Err)
                Return False
            End If

            '■変数の初期化
            '「ClsCommunicate」をNewする時、設定した

            '自分メールアドレスを抽出
            strMymailaddr = InitSettings.Instance.UserId & "@" & _
                InitSettings.Instance.SmtpServer.Substring(InitSettings.Instance.SmtpServer.IndexOf(".") + 1)

            '■メーリングリスト対象のリトライ項目の初期化
            RetryItems.sendMail = New CommStruct(InitSettings.Instance.MailingList.Count - 1) {}
            For i = 0 To InitSettings.Instance.MailingList.Count - 1
                RetryItems.sendMail(i).name = InitSettings.Instance.MailingList(i).SystemName
                RetryItems.sendMail(i).num = 0
            Next

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        Finally
            hDirInfoBar = Nothing
        End Try
    End Function

    '↓ UPD AT 2014/01/23 BY SHIN (仕様変更：パスフレーズ暗号化追加)

    ' ''' <summary>
    ' ''' 設定ファイルのパスワードのセキュリティ処理
    ' ''' </summary>
    ' ''' <returns>処理結果</returns>
    ' ''' <remarks></remarks>
    'Private Function onSecurityForPasswordByUserId() As Boolean
    '    Try
    '        '暗号化された場合、復号化する
    '        If InitSettings.Instance.Password.IndexOf(ClsStatic.INFO_OTHERS.Encrypted) >= 0 Then
    '            InitSettings.Instance.Password = clsOpenSSL.DecryptString( _
    '                getValueBySeek(InitSettings.Instance.Password, _
    '                               ClsStatic.INFO_OTHERS.Encrypted), _
    '                           InitSettings.Instance.UserId)
    '            '復号化結果のチェック
    '            If String.IsNullOrEmpty(InitSettings.Instance.Password) Then
    '                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_PASSWORD_Decrypt_ERR, ClsStatic.EventID.Err)
    '                Return False
    '            End If

    '            '暗号化されてない場合、暗号化し、保存する
    '        Else
    '            Dim strTemp As String = InitSettings.Instance.Password
    '            InitSettings.Instance.Password = clsOpenSSL.EncryptString(InitSettings.Instance.Password, _
    '                                                                      InitSettings.Instance.UserId)
    '            '暗号化結果のチェック
    '            If String.IsNullOrEmpty(InitSettings.Instance.Password) Then
    '                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_PASSWORD_Encrypt_ERR, ClsStatic.EventID.Err)
    '                Return False
    '            End If
    '            '暗号化されたデータを「Encrypted:暗号文」のようにフォーマットする
    '            InitSettings.Instance.Password = ClsStatic.INFO_OTHERS.Encrypted & InitSettings.Instance.Password

    '            '設定ファイルに保存
    '            If InitSettings.SaveToXmlFile(path.settings) = False Then
    '                WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_SAVE_ERR, ClsStatic.EventID.Err)
    '                Return False
    '            End If
    '            InitSettings.Instance.Password = strTemp
    '        End If

    '        Return True
    '    Catch ex As Exception
    '        SystemError.SystemLog(ex)
    '        Return False
    '    End Try
    'End Function

    ''' <summary>
    ''' 設定ファイルの項目をチェックし、暗号化して保存する
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <remarks></remarks>
    Private Function encryptByUserId() As Boolean
        Dim indexPassphrase As String
        Dim isEncrypted As Boolean = False
        Try
            '設定ファイルのパスワードを暗号化
            If InitSettings.Instance.Password.IndexOf(ClsStatic.INFO_OTHERS.Encrypted) < 0 Then

                InitSettings.Instance.Password = clsOpenSSL.EncryptString(InitSettings.Instance.Password, _
                                                                          InitSettings.Instance.UserId)
                '暗号化結果のチェック
                If String.IsNullOrEmpty(InitSettings.Instance.Password) Then
                    WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_PASSWORD_Encrypt_ERR, ClsStatic.EventID.Err)
                    Return False
                ElseIf isEncrypted = False Then : isEncrypted = True
                End If

                '暗号化されたデータを「Encrypted:暗号文」のようにフォーマットする
                InitSettings.Instance.Password = ClsStatic.INFO_OTHERS.Encrypted & InitSettings.Instance.Password
            End If

            '設定ファイルのパスフレーズを暗号化
            For i = 0 To InitSettings.Instance.MailingList.Count - 1
                For j = 0 To InitSettings.Instance.MailingList(i).OpenSslKeyList.Count - 1
                    indexPassphrase = InitSettings.Instance.MailingList(i).OpenSslKeyList(j).Passphrase

                    If indexPassphrase.IndexOf(ClsStatic.INFO_OTHERS.Encrypted) < 0 Then
                        indexPassphrase = clsOpenSSL.EncryptString(indexPassphrase, InitSettings.Instance.UserId)
                        '暗号化結果のチェック
                        If String.IsNullOrEmpty(indexPassphrase) Then
                            WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_Passphrase_Encrypt_ERR, ClsStatic.EventID.Err)
                            Return False
                        ElseIf isEncrypted = False Then : isEncrypted = True
                        End If

                        '暗号化されたデータを「Encrypted:暗号文」のようにフォーマットする
                        InitSettings.Instance.MailingList(i).OpenSslKeyList(j).Passphrase = _
                            ClsStatic.INFO_OTHERS.Encrypted & indexPassphrase
                    End If
                Next
            Next

            If isEncrypted Then
                '設定ファイルに保存
                If InitSettings.SaveToXmlFile(path.settings) = False Then
                    WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_SAVE_ERR, ClsStatic.EventID.Err)
                    Return False
                End If
            End If

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        Finally
            indexPassphrase = Nothing
            isEncrypted = Nothing
        End Try
    End Function

    ''' <summary>
    ''' 設定ファイルの項目を復号化
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <remarks></remarks>
    Private Function decryptByUserId() As Boolean
        Dim indexPassphrase As String
        Try
            '設定ファイルのパスワードを復号化
            If InitSettings.Instance.Password.IndexOf(ClsStatic.INFO_OTHERS.Encrypted) >= 0 Then
                InitSettings.Instance.Password = clsOpenSSL.DecryptString( _
                    getValueBySeek(InitSettings.Instance.Password, _
                                   ClsStatic.INFO_OTHERS.Encrypted), _
                               InitSettings.Instance.UserId)
                '復号化結果のチェック
                If String.IsNullOrEmpty(InitSettings.Instance.Password) Then
                    WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_PASSWORD_Decrypt_ERR, ClsStatic.EventID.Err)
                    Return False
                End If
            End If

            '設定ファイルのパスフレーズを復号化
            For i = 0 To InitSettings.Instance.MailingList.Count - 1
                For j = 0 To InitSettings.Instance.MailingList(i).OpenSslKeyList.Count - 1
                    indexPassphrase = InitSettings.Instance.MailingList(i).OpenSslKeyList(j).Passphrase

                    '暗号化された場合、復号化する
                    If indexPassphrase.IndexOf(ClsStatic.INFO_OTHERS.Encrypted) >= 0 Then
                        indexPassphrase = clsOpenSSL.DecryptString( _
                            getValueBySeek(indexPassphrase, ClsStatic.INFO_OTHERS.Encrypted), _
                            InitSettings.Instance.UserId)
                        '復号化結果のチェック
                        If String.IsNullOrEmpty(indexPassphrase) Then
                            WriteToEventLog(ClsStatic.MSG_EVENTLOG.SETTINGS_Passphrase_Decrypt_ERR, ClsStatic.EventID.Err)
                            Return False
                        End If
                        InitSettings.Instance.MailingList(i).OpenSslKeyList(j).Passphrase = indexPassphrase
                    End If
                Next
            Next

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        Finally
            indexPassphrase = Nothing
        End Try
    End Function
    '↑ UPD AT 2014/01/23 BY SHIN (仕様変更：パスフレーズ暗号化追加)

    ''' <summary>
    ''' フォルダを作成
    ''' </summary>
    Private Function createDirectory(ByVal strPath As String) As Boolean
        Try
            If Not System.IO.Directory.Exists(strPath) Then
                System.IO.Directory.CreateDirectory(strPath)
            End If

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' 設定ファイルの内容の整合性チェック
    ''' </summary>
    Private Function checkConfig() As Boolean
        Dim strMsg As String = Nothing

        Try
            strMsg &= checkItem("POPサーバー", InitSettings.Instance.PopServer, 255, False, True, "String")
            strMsg &= checkItem("SMTPサーバー", InitSettings.Instance.SmtpServer, 255, False, True, "String")
            strMsg &= checkItem("受信SSL使用有無", InitSettings.Instance.PopSsl, 5, False, True, "Boolean")
            strMsg &= checkItem("送信SSL使用有無", InitSettings.Instance.SmtpSsl, 5, False, True, "Boolean")
            strMsg &= checkItem("ユーザID", InitSettings.Instance.UserId, 50, False, True, "String")
            strMsg &= checkItem("パスワード", InitSettings.Instance.Password, 256, False, True, "String")
            strMsg &= checkItem("受信間隔（ミリ秒単位）", InitSettings.Instance.Interval, 8, False, True, "Integer")
            strMsg &= checkItem("POPポート", InitSettings.Instance.PopPort, 8, False, True, "Integer")
            strMsg &= checkItem("SMTPポート", InitSettings.Instance.SmtpPort, 8, False, True, "Integer")
            strMsg &= checkItem("ドメイン", InitSettings.Instance.Domain, 255, False, True, "String")
            strMsg &= checkItem("リトライ回数", InitSettings.Instance.RetryCount, 8, False, True, "Integer")
            strMsg &= checkItem("リトライ間隔", InitSettings.Instance.RetryTime, 8, False, True, "Integer", 60000)
            strMsg &= checkItem("自分メールに送信間隔", InitSettings.Instance.SendMailInterval, 8, False, True, "Integer")
            strMsg &= checkItem("バックアップファイルパス", InitSettings.Instance.OutputPath, 255, False, False, "String")
            strMsg &= checkItem("復号化キーパス", InitSettings.Instance.PrivateKeyPath, 255, False, False, "String")
            strMsg &= checkItem("宛先不明エラーメールタイトル", InitSettings.Instance.SendErrMailTitle, 255, False, False, "String")
            'strMsg &= checkItem("DB取込み機能エラーメールタイトル", InitSettings.Instance.DBErrMailTitle, 255, False, False, "String")
            'メーリングリスト
            For i = 0 To InitSettings.Instance.MailingList.Count - 1
                strMsg &= checkItem("対象システム名" & " " & i + 1, InitSettings.Instance.MailingList(i).SystemName, 200, False, False, "String")
                strMsg &= checkItem("アプリケーション名" & " " & i + 1, InitSettings.Instance.MailingList(i).ApplicationName, 200, False, False, "String")
                strMsg &= checkItem("宛先メールアドレス" & " " & i + 1, InitSettings.Instance.MailingList(i).AcceptMail, 255, False, True, "String")
                strMsg &= checkItem("宛先名" & " " & i + 1, InitSettings.Instance.MailingList(i).AcceptName, 100, True, False, "String")
                strMsg &= checkItem("件名" & " " & i + 1, InitSettings.Instance.MailingList(i).TitleName, 100, True, False, "String")
                strMsg &= checkItem("差出人名" & " " & i + 1, InitSettings.Instance.MailingList(i).SendName, 100, True, False, "String")
                strMsg &= checkItem("タイム略称" & " " & i + 1, InitSettings.Instance.MailingList(i).TimeAbbreviation, 5, False, True, "String")
                strMsg &= checkItem("時差" & " " & i + 1, InitSettings.Instance.MailingList(i).TimeDifference, 3, False, True, "Integer")
                For j = 0 To InitSettings.Instance.MailingList(i).OpenSslKeyList.Count - 1
                    strMsg &= checkItem("暗号キーID" & " " & i + 1 & "-" & j + 1, InitSettings.Instance.MailingList(i).OpenSslKeyList(j).PublicKey, 100, False, True, "String")
                    strMsg &= checkItem("復号化キー" & " " & i + 1 & "-" & j + 1, InitSettings.Instance.MailingList(i).OpenSslKeyList(j).PrivateKey, 256, False, True, "String")
                    strMsg &= checkItem("パスフレーズ" & " " & i + 1 & "-" & j + 1, InitSettings.Instance.MailingList(i).OpenSslKeyList(j).Passphrase, 100, False, True, "String")
                Next
            Next
            If Not String.IsNullOrEmpty(strMsg) Then
                SystemError.SystemLog(strMsg)
                Return False
            ElseIf Not String.IsNullOrEmpty(cTypeData()) Then
                SystemError.SystemLog(strMsg)
                Return False
            Else
                Return True
            End If
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' 設定ファイルの内容の整合性チェック
    ''' </summary>
    ''' <param name="itemName">設定ファイル項目</param>
    ''' <param name="itemValue">項目内容</param>
    ''' <param name="bteCount">バイト数</param>
    ''' <param name="isOmit">省略</param>
    ''' <param name="isEN">半角</param>
    ''' <returns>エラーメッセージ</returns>
    ''' <exception cref="Exception">チェック失敗</exception>
    Private Function checkItem(ByVal itemName As String, ByVal itemValue As Object, ByVal bteCount As Integer, _
                                 ByVal isOmit As Boolean, ByVal isEN As Boolean, ByVal itemType As String, _
                                 Optional ByVal maxValue As Object = Nothing) As String
        Dim retMsg As String = Nothing
        Try
            Dim bteCntItemName As Integer = System.Text.Encoding.GetEncoding("Shift_JIS").GetByteCount(itemName)
            Dim bteCntItemValue As Integer = System.Text.Encoding.GetEncoding("Shift_JIS").GetByteCount(itemValue.ToString)

            '省略不可のチェック
            If isOmit = False AndAlso String.IsNullOrEmpty(itemValue) Then
                retMsg &= ClsStatic.MSG_CHECK.OMIT

                '半角チェック
            ElseIf isEN AndAlso bteCntItemValue <> itemValue.ToString.Length Then
                retMsg &= ClsStatic.MSG_CHECK.EN

                'バイト数チェック
            ElseIf bteCntItemValue > bteCount Then
                retMsg &= bteCount & "バイト" & ClsStatic.MSG_CHECK.DATAOVER

                'データ型チェック
            ElseIf checkType(itemType, itemValue) = False Then
                'If String.IsNullOrEmpty(retMsg) = False Then
                '    retMsg &= SystemError.strSpace
                'End If
                retMsg &= ClsStatic.MSG_CHECK.TYPEERR

                '入力範囲チェック
            ElseIf maxValue IsNot Nothing Then

                Dim ConvertValue = Nothing

                Select Case itemType
                    Case "Integer"
                        ConvertValue = CType(itemValue, Integer)
                    Case "Long"
                        ConvertValue = CType(itemValue, Long)
                    Case Else

                End Select
                If ConvertValue > maxValue Then
                    retMsg &= maxValue & ClsStatic.MSG_CHECK.DATAOVER
                End If
            End If

            '改行で出力フォーマット（   XXXXXXXXXXXXXXXXXXXXXXXXX   :xxxxxxxx）  
            If String.IsNullOrEmpty(retMsg) = False Then
                Dim strLF = vbLf & SystemError.strSpace
                Dim cntSpace As Integer = 28

                Dim itemValueCorrect As String
                itemValueCorrect = itemName & _
                    Space(IIf(cntSpace - bteCntItemName < 0, SystemError.strSpace.Length, (cntSpace - bteCntItemName))) & CST_Colon
                retMsg = strLF & itemValueCorrect & retMsg
            End If

            Return retMsg
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return ex.Message
        End Try
    End Function

    ''' <summary>
    ''' データ型チェック
    ''' </summary>
    ''' <param name="strType">データ型</param>
    ''' <param name="strValue">データ</param>
    ''' <returns>チェック結果</returns>
    ''' <exception cref="Exception">チェック失敗</exception>
    Private Function checkType(ByVal strType As String, ByVal strValue As String) As Boolean
        Dim temp = Nothing
        Try
            Select Case strType
                Case "Boolean"
                    temp = CType(strValue, Boolean)
                Case "Integer"
                    temp = CType(strValue, Integer)
                Case "Long"
                    temp = CType(strValue, Long)
                Case Else

            End Select
            Return True
        Catch ex As Exception
            Return False
        End Try

    End Function

    ''' <summary>
    ''' データ型変更、ローカルに保存
    ''' </summary>
    ''' <returns>変更結果</returns>
    ''' <exception cref="Exception">変更失敗</exception>
    Private Function cTypeData() As String

        Try
            settings.PopSsl = Boolean.Parse(InitSettings.Instance.PopSsl)
            settings.SmtpSsl = Boolean.Parse(InitSettings.Instance.SmtpSsl)
            settings.PopPort = Integer.Parse(InitSettings.Instance.PopPort)
            settings.SmtpPort = Integer.Parse(InitSettings.Instance.SmtpPort)
            settings.RetryCount = Integer.Parse(InitSettings.Instance.RetryCount)
            settings.RetryTime = Integer.Parse(InitSettings.Instance.RetryTime)
            settings.SendMailInterval = Integer.Parse(InitSettings.Instance.SendMailInterval)
            settings.SendMailInterval = Integer.Parse(InitSettings.Instance.SendMailInterval)

            Return ""
        Catch ex As Exception
            Return ex.ToString
        End Try
    End Function

#End Region

#Region "メール送受信メイン処理"

    ''' <summary>
    ''' メール送受信処理
    ''' </summary>
    ''' <returns>メール送受信結果</returns>
    ''' <exception cref="Exception">メール送受信失敗</exception>
    Public Function mainMailer() As Boolean

        Try
            '■メールサーバに接続
            If executeRetry(RetryItems.connect.name) = False Then Return True

            '■ログイン
            If executeRetry(RetryItems.login.name) = False Then Return True

            '自分メールに送信チェック
            If checkSendMailToMyself() = False Then Return True

            '★受信処理：未読メールのUID、メッセージIDを取得
            If getNewMailInfo() = False Then Return True

            '■メール取得
            '受信スペードアップするため、降順で処理にする
            For i As Integer = 0 To newMailInfo.Count - 1

                '■ドメイン対象外のメールチェック＆処理
                Select Case checkExceptDoMain(i)
                    Case -1 : Return True
                    Case 0
                        '▲該当メールUIDがエラーメールUIDリストには存在であれば、削除する
                        updataUID(i, "OK")
                        Continue For
                End Select

                '★受信処理：メール本体を取得する
                If executeRetry(RetryItems.receiptMail.name, newMailInfo(i).num) = False Then Return True

                '■取得されたメール本文のアプリケーションより、メーリングリストから送信対象を抽出
                If getMailingByApplication(i) = False Then Continue For

                '■メール送信
                If executeRetry(indexSystemName, newMailInfo(i).num) = False Then
                    '▲エラーメールUIDを追加
                    updataUID(i, "NG")

                    Continue For
                End If

                '▲該当メールUIDがエラーメールUIDリストには存在であれば、削除する
                updataUID(i, "OK")

                '■抽出されたメールメールに削除マークを付ける
                If executeRetry(RetryItems.deleMail.name, newMailInfo(i).num) = False Then Return False

                '■CSVファイルに書き込む
                If writeCSV() = False Then
                    Dim errInfo As String = ClsStatic.MSG_EVENTLOG.DATA_BACKUP_ERR
                    If addDataToArrayList(lstErrData, "BACKUP") Then
                        'エラーイベントログ出力
                        WriteToEventLog(errInfo, ClsStatic.EventID.Err)
                    Else
                        '警告イベントログ出力（継続中）
                        WriteToEventLog(errInfo & ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, ClsStatic.EventID.Warning)
                    End If

                    Continue For
                Else
                    removeDataFromArrayList(lstErrData, "BACKUP")
                End If

            Next

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            'エラーイベントログ出力
            WriteToEventLog(ex.Message.ToString, ClsStatic.EventID.Err)
            Return True
        Finally
            Try
                '▲UIDファイルを保存
                If UidSettings.isChanged Then
                    If UidSettings.SaveToXmlFile(path.settings_uid) Then
                        UidSettings.isChanged = False
                    Else
                        'エラーイベントログ出力
                        WriteToEventLog(ClsStatic.MSG_EVENTLOG.UID_SAVE_ERR, ClsStatic.EventID.Err)
                        mainMailer = False
                    End If
                End If

                '通信終了、POP3コマンド「QUIT」
                If pop3Client.Connected Then pop3Client.Disconnect()
            Catch ex As Exception

            End Try
        End Try
    End Function

    ''' <summary>
    ''' ドメイン対象外のメールチェック＆処理
    ''' </summary>
    ''' <returns>処理結果
    ''' -1：エラー発生、処理中止
    ''' 0：ドメイン対象外、次のループに入る
    ''' 1：ドメイン対象、処理続き
    ''' </returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function checkExceptDoMain(ByVal i As Integer) As Integer
        Try
            '★受信処理：ドメイン対象を取得する
            indexMailHeader = Nothing
            If executeRetry(RetryItems.receiptMailDomainCount.name, newMailInfo(i).num) = False Then Return -1

            ''■DB取込み機能異常の通知メールがきた場合
            'If indexMailHeader.Subject.IndexOf(InitSettings.Instance.DBErrMailTitle) >= 0 Then
            '    '■抽出されたメールメールに削除マークを付ける
            '    indexSystemName = ClsStatic.MSG_EVENTLOG.MAILSERVER_DB_ERR
            '    If executeRetry(RetryItems.deleMail.name, i) = False Then Return False
            '    'イベントログに出力
            '    WriteToEventLog(ClsStatic.MSG_EVENTLOG.MAILSERVER_DB_ERR, ClsStatic.EventID.Err)

            '    Continue For
            'End If

            '■宛先不明でメールが戻ってきた場合
            If indexMailHeader.Subject.IndexOf(InitSettings.Instance.SendErrMailTitle) >= 0 Then
                '送信エラーメーリング対象のシステム名を抽出
                indexSystemName = getErrSystemName(newMailInfo(i).num)
                '■抽出されたメールメールに削除マークを付ける
                If executeRetry(RetryItems.deleMail.name, newMailInfo(i).num) = False Then Return -1
                'イベントログに出力
                WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_Undeliverable, _
                                                indexSystemName), ClsStatic.EventID.Err)

                Return 0
            End If

            '■自分のメールアドレスの場合
            If strMymailaddr.Equals(indexMailHeader.From.MailAddress.Address) Then
                '自分メールがある場合、受信フラグをセット（1：正常（受信））
                flgReceipt = 1

                '■抽出されたメールメールに削除マークを付ける
                indexSystemName = ClsStatic.INFO_OTHERS.MyselfSystemName
                If executeRetry(RetryItems.deleMail.name, newMailInfo(i).num) = False Then Return -1

                Return 0
            End If

            '■設定ファイルの「ドメイン」
            If InitSettings.Instance.Domain.Equals(indexMailHeader.From.MailAddress.Host) = False Then
                '対象外メールの場合

                Return 0
            End If

            Return 1
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return -1
        End Try

    End Function

    ''' <summary>
    ''' 取得されたメール本文のアプリケーションより、メーリングリストから送信対象を抽出
    ''' 送信データ編集
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function getMailingByApplication(ByVal i As Integer) As Boolean
        Try
            '取得されたメール本文の暗号化キーを取得
            Dim strPublicKey As String = MailItemValue.mailItems(MailItemValue.mailItems.Count - 1).value
            If Not String.IsNullOrEmpty(strPublicKey) Then
                strPublicKey = strPublicKey.Substring(strPublicKey.IndexOf(CST_Equal) + 1).Trim
            Else
                strPublicKey = String.Empty
            End If

            '■取得されたメール本文のアプリケーションを取得し、システムを判別する
            Dim strApplication As String = MailItemValue.mailItems(7).value
            If Not String.IsNullOrEmpty(strApplication) Then
                strApplication = getValueBySeek(strApplication, CST_Colon).Trim
            Else
                strApplication = String.Empty
            End If
            '取得されたメール本文の暗号化キーが設定ファイルの「暗号化キー」には位置を抽出
            indexXY = Nothing
            indexXY = getMailingItems(strApplication, strPublicKey)

            '■メール本文のアプリケーションが設定ファイルの「システム名」には存在しない場合
            If indexXY Is Nothing Then
                Dim errInfo As String = String.Format(ClsStatic.MSG_EVENTLOG.APPLICATION_NOTEXIST, strApplication)
                If addDataToArrayList(lstErrData, strApplication) Then
                    'エラーイベントログ出力
                    WriteToEventLog(errInfo, ClsStatic.EventID.Err)
                Else
                    '警告イベントログ出力（継続中）
                    WriteToEventLog(errInfo & ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, ClsStatic.EventID.Warning)
                End If

                '▲エラーメールUIDを追加
                updataUID(i, "NG")

                Return False
            Else
                removeDataFromArrayList(lstErrData, strApplication)
            End If

            '■送信データ編集処理
            editMailItemValue(strPublicKey)

            '設定ファイルから当対象システム名を取得
            indexSystemName = InitSettings.Instance.MailingList(indexXY(0)).SystemName

            Return True
        Catch ex As Exception
            '▲エラーメールUIDを追加
            updataUID(i, "NG")
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function
    ''' <summary>
    ''' 証明書を無視するコールバック関数
    ''' </summary>
    ''' <returns>信頼されないSSL証明書を回避</returns>
    Private Function validateServerCertificate(sender As Object, certificate As System.Security.Cryptography.X509Certificates.X509Certificate, _
                                                     chain As System.Security.Cryptography.X509Certificates.X509Chain, _
                                                     sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
        Return True
    End Function

    ''' <summary>
    '''メールサーバに接続
    ''' </summary>
    ''' <returns>接続結果</returns>
    ''' <exception cref="Exception">接続失敗</exception>
    Private Function connect() As Boolean
        Try
            If Not pop3Client.Connected Then
                'pop3Client.Connect(InitSettings.Instance.PopServer, settings.PopPort, settings.PopSsl)
                pop3Client.Connect(InitSettings.Instance.PopServer, settings.PopPort, settings.PopSsl, _
                                   ClsStatic.defaultTimeOut, ClsStatic.defaultTimeOut, _
                                    New System.Net.Security.RemoteCertificateValidationCallback(AddressOf validateServerCertificate))
            End If

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try

    End Function

    ''' <summary>
    ''' ログイン
    ''' </summary>
    ''' <returns>ログイン結果</returns>
    ''' <exception cref="Exception">読み込み失敗</exception>
    Private Function login() As Boolean
        Try
            pop3Client.Authenticate(InitSettings.Instance.UserId, InitSettings.Instance.Password)
            ''ローカル環境でテスト用
            'pop3Client.Authenticate(InitSettings.Instance.UserId & "@mizuho.com", InitSettings.Instance.Password)

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' メールの件数を取得する
    ''' </summary>
    ''' <returns>取得結果</returns>
    ''' <exception cref="Exception">取得失敗</exception>
    Private Function getMailCount() As Integer
        Try
            Return pop3Client.GetMessageCount()

        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return -1
        End Try
    End Function

    ''' <summary>
    ''' ドメイン対象を取得する
    ''' </summary>
    ''' <returns>取得結果</returns>
    ''' <exception cref="Exception">取得失敗</exception>
    Private Function getMailHeader(ByVal i As Integer) As OpenPop.Mime.Header.MessageHeader
        Try
            Return pop3Client.GetMessageHeaders(i + 1)
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return Nothing
        End Try
    End Function

    ''' <summary>
    ''' メールのUIDを取得する
    ''' </summary>
    ''' <returns>取得結果</returns>
    ''' <exception cref="Exception">取得失敗</exception>
    Private Function getMailUids() As List(Of String)
        Try
            Return pop3Client.GetMessageUids()
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return Nothing
        End Try
    End Function

    ''' <summary>
    ''' 抽出されたメールメールに削除マークを付ける。
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function deleteMail(ByVal i As Integer) As Boolean
        Try
            pop3Client.DeleteMessage(i + 1)

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

#End Region

#Region "リトライ処理"

    ''' <summary>
    ''' リトライ処理
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function executeRetry(ByVal retryItem As String, Optional ByVal i As Integer = -1, _
                                  Optional ByRef obj As Object = Nothing) As Boolean
        'チェック結果(0:成功；1：警告；2:エラー；3:エラー継続中)
        Dim checkResult As Integer = 0
        Dim cnt As Integer = 0
        Try

            Select Case retryItem

                Case RetryItems.connect.name
                    '■メールサーバに接続
                    checkResult = checkRetry(connect() = False, RetryItems.connect.num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_CONNECT_ERR_N, _
                                                             RetryItems.connect.num), ClsStatic.EventID.Warning)
                    ElseIf checkResult = 2 Then
                        'エラーイベントログ出力
                        WriteToEventLog(ClsStatic.MSG_EVENTLOG.MAILSERVER_CONNECT_ERR, ClsStatic.EventID.Err)
                        Return False
                    ElseIf checkResult = 3 Then
                        '警告イベントログ出力（継続中）
                        cnt = IIf(RetryItems.connect.num Mod settings.RetryCount = 0, _
                                     settings.RetryCount, RetryItems.connect.num Mod settings.RetryCount)
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_CONNECT_ERR_N & _
                                                      ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, _
                                                      cnt), ClsStatic.EventID.Warning)
                        'リトライ回数になった場合、リトライ処理終了
                        If RetryItems.connect.num Mod settings.RetryCount = 0 Then Return False
                    End If

                Case RetryItems.login.name
                    '■ログイン
                    checkResult = checkRetry(login() = False, RetryItems.login.num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_LOGIN_ERR_N, _
                                                                RetryItems.login.num), ClsStatic.EventID.Warning)
                    ElseIf checkResult = 2 Then
                        'エラーイベントログ出力
                        WriteToEventLog(ClsStatic.MSG_EVENTLOG.MAILSERVER_LOGIN_ERR, ClsStatic.EventID.Err)
                        Return False
                    ElseIf checkResult = 3 Then
                        '警告イベントログ出力（継続中）
                        cnt = IIf(RetryItems.login.num Mod settings.RetryCount = 0, _
                                     settings.RetryCount, RetryItems.login.num Mod settings.RetryCount)
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_LOGIN_ERR_N & _
                                                      ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, _
                                                      cnt), ClsStatic.EventID.Warning)
                        'リトライ回数になった場合、リトライ処理終了
                        If RetryItems.login.num Mod settings.RetryCount = 0 Then Return False
                    End If

                Case RetryItems.sendMailToMyself.name
                    '■自分メールに送信
                    checkResult = checkRetry(sendToMe() = False, RetryItems.sendMailToMyself.num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_SEND_ERR_N, _
                                                                 ClsStatic.INFO_OTHERS.MyselfSystemName, _
                                                                 RetryItems.sendMailToMyself.num), ClsStatic.EventID.Warning)
                    ElseIf checkResult = 2 Then
                        'エラーイベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_SEND_ERR, _
                                                      ClsStatic.INFO_OTHERS.MyselfSystemName), ClsStatic.EventID.Err)
                        Return False
                    ElseIf checkResult = 3 Then
                        '警告イベントログ出力（継続中）
                        cnt = IIf(RetryItems.sendMailToMyself.num Mod settings.RetryCount = 0, _
                                     settings.RetryCount, RetryItems.sendMailToMyself.num Mod settings.RetryCount)
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_SEND_ERR_N & _
                                                      ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, _
                                                      cnt), ClsStatic.EventID.Warning)
                        'リトライ回数になった場合、リトライ処理終了
                        If RetryItems.sendMailToMyself.num Mod settings.RetryCount = 0 Then Return False
                    End If

                Case RetryItems.receiptMailCount.name
                    Const CST_List As String = "一覧"

                    '■メール件数を取得
                    obj = getMailUids()

                    checkResult = checkRetry(obj Is Nothing, RetryItems.receiptMailCount.num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR_N, _
                                                      CST_List, _
                                                      RetryItems.receiptMailCount.num), ClsStatic.EventID.Warning)
                    ElseIf checkResult = 2 Then
                        'エラーイベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR, _
                                                      CST_List), ClsStatic.EventID.Err)
                        Return False
                    ElseIf checkResult = 3 Then
                        '警告イベントログ出力（継続中）
                        cnt = IIf(RetryItems.receiptMailCount.num Mod settings.RetryCount = 0, _
                                     settings.RetryCount, RetryItems.receiptMailCount.num Mod settings.RetryCount)
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR_N & _
                                                      ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, _
                                                      CST_List, _
                                                      cnt), ClsStatic.EventID.Warning)
                        'リトライ回数になった場合、リトライ処理終了
                        If RetryItems.receiptMailCount.num Mod settings.RetryCount = 0 Then Return False
                    End If

                Case RetryItems.receiptMailDomainCount.name
                    Const CST_Domain As String = "ドメイン"

                    '■ドメイン対象を取得する
                    indexMailHeader = getMailHeader(i)
                    checkResult = checkRetry(indexMailHeader Is Nothing, RetryItems.receiptMailDomainCount.num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR_N, _
                                                      CST_Domain, _
                                                      RetryItems.receiptMailDomainCount.num), ClsStatic.EventID.Warning)
                    ElseIf checkResult = 2 Then
                        'エラーイベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR, _
                                                      CST_Domain), ClsStatic.EventID.Err)
                        Return False
                    ElseIf checkResult = 3 Then
                        '警告イベントログ出力（継続中）
                        cnt = IIf(RetryItems.receiptMailDomainCount.num Mod settings.RetryCount = 0, _
                                     settings.RetryCount, RetryItems.receiptMailDomainCount.num Mod settings.RetryCount)
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR_N & _
                                                      ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, _
                                                      CST_Domain, _
                                                      cnt), ClsStatic.EventID.Warning)
                        'リトライ回数になった場合、リトライ処理終了
                        If RetryItems.receiptMailDomainCount.num Mod settings.RetryCount = 0 Then Return False
                    End If

                Case RetryItems.receiptMail.name
                    Const CST_Body As String = "本体"

                    '■メール本体を取得する
                    checkResult = checkRetry(acceptMail(i) = False, RetryItems.receiptMail.num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR_N, _
                                                      CST_Body, _
                                                      RetryItems.receiptMail.num), ClsStatic.EventID.Warning)
                    ElseIf checkResult = 2 Then
                        'エラーイベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR, _
                                                      CST_Body), ClsStatic.EventID.Err)
                        Return False
                    ElseIf checkResult = 3 Then
                        '警告イベントログ出力（継続中）
                        cnt = IIf(RetryItems.receiptMail.num Mod settings.RetryCount = 0, _
                                     settings.RetryCount, RetryItems.receiptMail.num Mod settings.RetryCount)
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_RECEIPT_ERR_N & _
                                                      ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, _
                                                      CST_Body, _
                                                      cnt), ClsStatic.EventID.Warning)
                        'リトライ回数になった場合、リトライ処理終了
                        If RetryItems.receiptMail.num Mod settings.RetryCount = 0 Then Return False
                    End If

                Case indexSystemName 'RetryItems.sendMail.name
                    Dim j As Integer = 0
                    Dim errInfo As String = Nothing

                    For j = 0 To RetryItems.sendMail.Count - 1
                        If RetryItems.sendMail(j).name.Equals(indexSystemName) Then Exit For
                    Next

                    '■メール送信
                    checkResult = checkRetry(sendMail(indexXY(0)) = False, RetryItems.sendMail(j).num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_SEND_ERR_N, _
                                                            indexSystemName, RetryItems.sendMail(j).num), ClsStatic.EventID.Warning)
                    ElseIf checkResult = 2 Then
                        errInfo = String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_SEND_ERR, indexSystemName)
                        'エラーイベントログ出力
                        WriteToEventLog(errInfo, ClsStatic.EventID.Err)

                        Return False
                    ElseIf checkResult = 3 Then
                        '警告イベントログ出力（継続中）
                        cnt = IIf(RetryItems.sendMail(j).num Mod settings.RetryCount = 0, _
                                     settings.RetryCount, RetryItems.sendMail(j).num Mod settings.RetryCount)

                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_SEND_ERR_N & _
                                                      ClsStatic.MSG_EVENTLOG.MAILSERVER_CONTINUING_ERR, _
                                                      indexSystemName, cnt), ClsStatic.EventID.Warning)
                        'リトライ回数になった場合、リトライ処理終了
                        If RetryItems.sendMail(j).num Mod settings.RetryCount = 0 Then Return False
                    End If

                Case RetryItems.deleMail.name
                    '▲UIDで判断するため、削除しないようにチェックする
                    If ClsStatic.isDelete = False Then Return True

                    '■抽出されたメールメールに削除マークを付ける
                    checkResult = checkRetry(deleteMail(i) = False, RetryItems.deleMail.num)

                    If checkResult = 1 Then
                        '警告イベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_DELE_ERR_N, _
                                                            indexSystemName, RetryItems.deleMail.num), ClsStatic.EventID.Warning)
                    ElseIf checkResult > 1 Then
                        'エラーイベントログ出力
                        WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.MAILSERVER_DELE_ERR, indexSystemName), ClsStatic.EventID.Err)
                        Return False
                    End If

                Case Else
                    Return False
            End Select


            If checkResult = 0 Then Return True

            System.Threading.Thread.Sleep(settings.RetryTime)
            Return executeRetry(retryItem, i)

        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False

        End Try
    End Function

    ''' <summary>
    ''' リトライ回数チェック
    ''' </summary>
    ''' <returns>チェック結果(0:成功；1：警告；2:エラー；3:エラー継続中)</returns>
    ''' <exception cref="Exception">チェック失敗</exception>
    Private Function checkRetry(ByVal bln As Boolean, ByRef retryCount As Integer) As Integer
        Try
            retryCount = IIf(bln, retryCount + 1, 0)

            If bln = False Then
                Return 0

            ElseIf retryCount < settings.RetryCount Then
                Return 1

            ElseIf retryCount = settings.RetryCount Then
                'retryCount = 0
                Return 2

            ElseIf retryCount > settings.RetryCount Then
                retryCount = retryCount Mod settings.RetryCount + settings.RetryCount
                Return 3
            End If

            Return 2
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return 2
        End Try
    End Function

    ''' <summary>
    ''' リスト更新処理
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function removeDataFromArrayList(ByRef arr As List(Of String), ByVal strItem As String) As Boolean
        Try
            For i = 0 To arr.Count - 1
                If arr.Item(i).ToString.Equals(strItem) Then
                    arr.RemoveAt(i)
                    Return True
                End If
            Next

            Return False
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' リスト追加処理
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function addDataToArrayList(ByRef arr As List(Of String), ByVal strItem As String) As Boolean
        Try
            For i = 0 To arr.Count - 1
                If arr.Item(i).ToString.Equals(strItem) Then
                    Return False
                End If
            Next

            arr.Add(strItem)
            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' UIDファイルを更新
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function updataUID(ByVal i As Integer, ByVal flg As String) As Boolean
        Try

            Select Case flg

                Case "NG"
                    '処理失敗の場合、MaxUID、エラーUIDリストを更新
                    addDataToArrayList(UidSettings.Instance.ErrUids, newMailInfo(i).name)
                    UidSettings.Instance.MaxUid = newMailInfo(i).name

                    '処理成功の場合、MaxUIDを更新、エラーUIDリストから削除
                Case "OK"
                    If newMailInfo(i).isErrObj Then
                        removeDataFromArrayList(UidSettings.Instance.ErrUids, newMailInfo(i).name)
                    Else
                        UidSettings.Instance.MaxUid = newMailInfo(i).name
                    End If

                    'メール件数統計（テスト用）
                    cntMail += 1
            End Select

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

#End Region

#Region "メール受信処理"

    ''' <summary>
    ''' '▲未読メールのUID、メッセージIDを取得
    ''' </summary>
    ''' <returns>取得結果</returns>
    ''' <exception cref="Exception">取得失敗</exception>
    Private Function getNewMailInfo()
        Dim lstUids As List(Of String) = Nothing
        Try

            '★受信処理：メールボックスに全てのメールのUID、メッセージIDを取得する
            If executeRetry(RetryItems.receiptMailCount.name, 1, lstUids) = False Then Return False
            If lstUids Is Nothing OrElse lstUids.Count <= 0 Then Return False

            newMailInfo = Nothing

            'UIDファイルが存在するかのチェック
            If Not System.IO.File.Exists(path.settings_uid) OrElse String.IsNullOrEmpty(UidSettings.Instance.MaxUid) Then
                'UIDファイルが不存在の場合、
                newMailInfo = New CommStruct(lstUids.Count - 1) {}
                For i = 0 To lstUids.Count - 1
                    newMailInfo(i) = New CommStruct(lstUids(i), i)
                Next
            Else
                'UIDファイルが存在の場合、UIDファイルの「エラーUIDリスト」件数＋UIDファイルの「MaxUid」以降のメール件数を取得

                Dim cnt As Integer = 0
                'UIDファイルの「エラーUIDリスト」のメッセージIDを抽出
                If UidSettings.Instance.ErrUids IsNot Nothing AndAlso _
                    UidSettings.Instance.ErrUids.Count > 0 Then

                    'NewMailInfo = New CommStruct((UidSettings.Instance.ErrUids.Count - 1)) {}

                    cnt = 0

                    Dim tempErrUids As List(Of String) = UidSettings.Instance.ErrUids
                    For i = 0 To lstUids.Count - 1

                        If tempErrUids Is Nothing OrElse tempErrUids.Count = 0 Then Exit For

                        For j = 0 To tempErrUids.Count - 1
                            If lstUids.Item(i).Equals(tempErrUids(j)) Then
                                ReDim Preserve newMailInfo(cnt)
                                newMailInfo(cnt) = New CommStruct(lstUids(i), i, True)
                                tempErrUids.RemoveAt(j)
                                cnt += 1
                                Exit For
                            End If
                        Next
                    Next
                End If

                'UIDファイルの「MaxUid」以降のメッセージIDを抽出
                Dim isStart As Boolean = False
                cnt = 0
                If newMailInfo IsNot Nothing Then
                    cnt = newMailInfo.Count
                End If

                For i = 0 To lstUids.Count - 1
                    '"1000"<"999"
                    If isStart OrElse lstUids.Item(i) > UidSettings.Instance.MaxUid OrElse _
                        lstUids.Item(i).Length > UidSettings.Instance.MaxUid.Length Then
                        If isStart = False Then
                            isStart = True
                            ReDim Preserve newMailInfo(cnt + lstUids.Count - (i + 1))
                        End If
                        newMailInfo(cnt) = New CommStruct(lstUids(i), i)
                        cnt += 1
                    End If
                Next
            End If

            'メール件数=0 の場合
            If newMailInfo Is Nothing OrElse newMailInfo.Count = 0 Then
                Return False
            Else
                Return True
            End If
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        Finally
            lstUids = Nothing
        End Try
    End Function
    
    ''' <summary>
    ''' メール受信処理
    ''' </summary>
    ''' <returns>取得結果</returns>
    ''' <exception cref="Exception">取得失敗</exception>
    Private Function acceptMail(ByVal index As Integer) As Boolean
        Dim strLine, strValue, strBefor As String
        Dim strBody As String = ""
        Dim strUserData As String = ""
        Dim isUserData As Boolean = False
        Dim oMail As OpenPop.Mime.Message
        Dim rs As System.IO.StringReader
        Dim i, j As Integer

        Dim lstMailBody As New List(Of String)
        Const CST_Separator As String = "#"
        Const CST_ItemType As String = "Feed item type: Pinpoint malware detected machine"
        Const CST_ItemData As String = "data"
        Const CST_ItemKey As String = "key_id"

        Try
            'メール項目の初期化設定
            For i = 0 To mailItemList.Length - 1
                mailItemList(i).value = Nothing
            Next
            MailItemValue.resultDecrypt = Nothing
            MailItemValue.mailItems = mailItemList
            MailItemValue.titleName = Nothing
            MailItemValue.body = Nothing

            'メール本文取得
            oMail = pop3Client.GetMessage(index + 1)
            rs = New System.IO.StringReader(oMail.FindFirstPlainTextVersion.GetBodyAsText)
            MailItemValue.titleName = oMail.Headers.Subject

            'メール項目の読込
            While rs.Peek() > -1
                strLine = rs.ReadLine()
                If strLine Is Nothing Then Exit While
                If strLine.TrimEnd.Equals(String.Empty) Then Continue While
                lstMailBody.Add(strLine)
                strBody &= strLine & CST_Separator
            End While

            'メール項目のチェック、保存
            For i = 0 To MailItemValue.mailItems.Length - 1

                If lstMailBody Is Nothing OrElse lstMailBody.Count = 0 Then Exit For

                For j = 0 To lstMailBody.Count - 1
                    strLine = lstMailBody.Item(j)
                    If String.IsNullOrEmpty(strLine) Then Continue For
                    strValue = Nothing

                    Select Case MailItemValue.mailItems(i).oldItem
                        'Feed 種別の場合、全行日本語化
                        Case CST_ItemType
                            If strLine.IndexOf(MailItemValue.mailItems(i).oldItem) >= 0 Then
                                strValue = strLine.Replace(MailItemValue.mailItems(i).oldItem, MailItemValue.mailItems(i).newItem)
                            Else
                                Continue For
                            End If

                            '暗号化データの場合
                        Case CST_ItemData
                            strBefor = getValueBySeek(strLine, CST_Equal, False)
                            If isUserData = False AndAlso _
                                strBefor.IndexOf(MailItemValue.mailItems(i).oldItem) >= 0 Then

                                lstMailBody.Item(j) = Nothing
                                isUserData = True
                                Continue For

                                '暗号化データを収集
                            ElseIf isUserData Then
                                If strBefor.IndexOf(CST_ItemKey) < 0 Then
                                    strUserData &= strLine.Trim
                                    lstMailBody.Item(j) = Nothing
                                    Continue For
                                Else
                                    MailItemValue.mailItems(i).value = strUserData
                                    strUserData = String.Empty
                                    isUserData = False
                                    Exit For
                                End If
                            Else
                                Continue For
                            End If

                            '暗号化キーの場合
                            'Case CST_ItemKey

                            '上記以外の場合
                        Case Else
                                strBefor = getValueBySeek(strLine, CST_Colon, False)
                                If strBefor.IndexOf(MailItemValue.mailItems(i).oldItem) >= 0 Then
                                    strValue = strBefor.Replace(MailItemValue.mailItems(i).oldItem, _
                                                                MailItemValue.mailItems(i).newItem) _
                                        & getValueBySeek(strLine, strBefor)
                                Else
                                    Continue For
                                End If

                    End Select

                    MailItemValue.mailItems(i).value = strValue
                    lstMailBody.Item(j) = Nothing
                    Exit For
                Next
            Next

            MailItemValue.body = Left(strBody.Trim, strBody.Trim.Length - 1)

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        Finally
            strLine = Nothing
            strValue = Nothing
            oMail = Nothing
            rs = Nothing
        End Try
    End Function

    ''' <summary>
    ''' 送信エラーメーリング対象のシステム名を抽出
    ''' </summary>
    ''' <returns>メーリング対象のシステム名</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function getErrSystemName(ByVal index As Integer) As String
        Dim oMail As OpenPop.Mime.Message
        Dim indexAcceptMail, mailBody As String

        Try
            'メール本文取得
            oMail = pop3Client.GetMessage(index + 1)
            mailBody = oMail.FindFirstPlainTextVersion.GetBodyAsText
            '送信エラーメーリング対象のシステム名を抽出
            For i = 0 To InitSettings.Instance.MailingList.Count - 1
                indexAcceptMail = InitSettings.Instance.MailingList(i).AcceptMail
                If mailBody.IndexOf(indexAcceptMail) >= 0 Then
                    Return InitSettings.Instance.MailingList(i).SystemName
                End If
            Next
            Return Nothing
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return Nothing
        Finally
            oMail = Nothing
            indexAcceptMail = Nothing
            mailBody = Nothing
        End Try
    End Function

#End Region

#Region "メール送信処理"

    ''' <summary>
    ''' メール送信処理
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function sendMail(ByVal indexX As Integer) As Boolean

        'MailMessageの作成
        Dim msg As New System.Net.Mail.MailMessage()
        Try
            Dim sc As New System.Net.Mail.SmtpClient()
            'SMTPサーバーを指定する
            sc.Host = InitSettings.Instance.SmtpServer '←SMTPサーバ指定

            sc.Credentials = New System.Net.NetworkCredential(strMymailaddr, InitSettings.Instance.Password) '←SSL認証用ユーザー名（メールアドレス）とパスワードを指定
            sc.Port = settings.SmtpPort 'ポートを指定
            sc.EnableSsl = settings.SmtpSsl 'SSL認証を使うか指定

            '件名
            If String.IsNullOrEmpty(InitSettings.Instance.MailingList(indexX).TitleName) Then
                msg.Subject = MailItemValue.titleName '"件名"
            Else
                msg.Subject = InitSettings.Instance.MailingList(indexX).TitleName '"件名"
            End If
            msg.To.Add(New System.Net.Mail.MailAddress(InitSettings.Instance.MailingList(indexX).AcceptMail, InitSettings.Instance.MailingList(indexX).AcceptName))
            msg.From = New System.Net.Mail.MailAddress(strMymailaddr, InitSettings.Instance.MailingList(indexX).SendName)

            For i = 0 To MailItemValue.mailItems.Length - 1
                If MailItemValue.mailItems(i).outputLevel = 1 AndAlso _
                    Not String.IsNullOrEmpty(MailItemValue.mailItems(i).value) Then

                    If Not String.IsNullOrEmpty(msg.Body) Then msg.Body &= vbLf
                    msg.Body &= MailItemValue.mailItems(i).value

                End If
            Next

            sc.Send(msg)

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        Finally
            '後始末
            msg.Dispose()
        End Try
    End Function

    ''' <summary>
    ''' メールサーバー監視
    ''' </summary>
    ''' <returns>メールサーバー監視</returns>
    ''' <exception cref="Exception">メールサーバー監視</exception>
    Private Function sendToMe() As Boolean

        'MailMessageの作成
        Dim msg As New System.Net.Mail.MailMessage()

        Try

            Dim sc As New System.Net.Mail.SmtpClient()
            'SMTPサーバーを指定する
            sc.Host = InitSettings.Instance.SmtpServer '←SMTPサーバ指定

            sc.Credentials = New System.Net.NetworkCredential(strMymailaddr, InitSettings.Instance.Password) '←SSL認証用ユーザー名（メールアドレス）とパスワードを指定
            sc.Port = settings.SmtpPort 'ポートを指定
            sc.EnableSsl = settings.PopSsl 'SSL認証を使うか指定

            '宛先
            msg.To.Add(strMymailaddr)
            '件名
            msg.Subject = ClsStatic.INFO_OTHERS.ToMyselfMailTitle '"件名"
            msg.From = New System.Net.Mail.MailAddress(strMymailaddr, "")
            sc.Send(msg)

            '後始末
            msg.Dispose()

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' 送信データ編集処理
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function editMailItemValue(ByVal strPublicKey As String) As String
        Dim retErrMsg As String = ""
        Dim strUseId As String = ""

        '受信時刻をシステム時間にする（設定ファイルの「タイム略称、時差」より
        Dim strReceived As String = MailItemValue.mailItems(1).value
        If Not String.IsNullOrEmpty(strReceived) Then
            Try
                Dim strDateTime As String = strReceived.Substring(strReceived.IndexOf(":") + 1).Trim

                settings.TimeDifference = Integer.Parse(InitSettings.Instance.MailingList(indexXY(0)).TimeDifference)
                Dim dtTime As DateTime = DateTime.Parse(strDateTime.Substring(0, 19)).AddHours(settings.TimeDifference)

                MailItemValue.mailItems(1).value = strReceived.Replace(strDateTime, dtTime.ToString("yyyy-MM-dd HH:mm:ss ") & _
                                                                        InitSettings.Instance.MailingList(indexXY(0)).TimeAbbreviation)
            Catch ex As Exception
                retErrMsg &= InitSettings.Instance.MailingList(indexXY(0)).SystemName & _
                    "の受信時刻のフォーマット不正"
                MailItemValue.mailItems(1).value = strReceived
                'エラーイベントログ出力
                WriteToEventLog(retErrMsg, ClsStatic.EventID.Err)
            End Try
        End If

        '暗号化されたデータを取得
        Dim strDecryptData As String = MailItemValue.mailItems(MailItemValue.mailItems.Count - 2).value
        strUseId = strDecryptData
        '暗号化されたデータが不存在の場合、復号化キーなし、ユーザIDを空にする
        If String.IsNullOrEmpty(strDecryptData) Then
            '■複合化結果を保存
            MailItemValue.resultDecrypt = 0
            Return retErrMsg
        End If

        '■メール本文の暗号化キーが設定ファイルの「暗号化キー」には存在しない場合
        If indexXY(1) = -1 Then
            'エラーイベントログ出力
            'strPublicKey{0}は、メール本文の暗号化キー
            WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.DECRYPT_KEY_NOTEXIST, strPublicKey), ClsStatic.EventID.Err)
            '■複合化結果を保存
            MailItemValue.resultDecrypt = 0

            '■メール本文の暗号化キーが設定ファイルの「暗号化キー」には存在する場合
        Else
            '設定ファイルから復号化キーを取得
            Dim strPrivateKey As String = InitSettings.Instance.MailingList(indexXY(0)).OpenSslKeyList(indexXY(1)).PrivateKey
            '設定ファイルからパスフレーズを取得
            Dim strPassphrase As String = InitSettings.Instance.MailingList(indexXY(0)).OpenSslKeyList(indexXY(1)).Passphrase

            '■設定ファイルの「復号化キーパス」より、復号化キーファイルが存在しない場合
            If Not System.IO.File.Exists(path.openSslKey & strPrivateKey) Then
                'エラーイベントログ出力（出力メッセージ内容【復号化キーファイルが存在しない】）
                'strPublicKey{0}は、メール本文の暗号化キー
                WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.DECRYPT_FILE_NOTEXIST, strPublicKey), ClsStatic.EventID.Err)
                '■複合化結果を保存
                MailItemValue.resultDecrypt = 0
            Else
                'ユーザIDを複合化する
                strUseId = clsOpenSSL.Decrypt(strDecryptData, path.openSslKey & strPrivateKey, strPassphrase)
                If String.IsNullOrEmpty(strUseId) Then
                    '■ユーザIDの復号化失敗の場合
                    'strPublicKey{0}は、メール本文の暗号化キー
                    WriteToEventLog(String.Format(ClsStatic.MSG_EVENTLOG.DECRYPT_ERR, strPublicKey), ClsStatic.EventID.Err)
                    strUseId = strDecryptData
                    '■複合化結果を保存
                    MailItemValue.resultDecrypt = 0
                Else
                    '■複合化結果を保存
                    MailItemValue.resultDecrypt = 1
                End If
            End If
        End If


        '複合化されたユーザーIDを設定
        MailItemValue.mailItems(MailItemValue.mailItems.Count - 3).value = _
            MailItemValue.mailItems(MailItemValue.mailItems.Count - 3).value.Trim & " " & strUseId

        Return retErrMsg
    End Function

    ''' <summary>
    ''' 取得されたメール本文の暗号化キーが設定ファイルの「暗号化キー」には位置を抽出
    ''' </summary>
    ''' <returns>メーリング対象の位置</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function getMailingItems(ByVal strApplication As String, ByVal strPublicKey As String) As Integer()

        If String.IsNullOrEmpty(strApplication) Then Return Nothing

        '暗号化キーより、メーリング対象を抽出
        For i = 0 To InitSettings.Instance.MailingList.Count - 1
            If InitSettings.Instance.MailingList(i).ApplicationName.Equals(strApplication) Then

                If String.IsNullOrEmpty(strPublicKey) Then
                    Return New Integer(1) {i, -1}
                End If

                For j As Integer = 0 To InitSettings.Instance.MailingList(i).OpenSslKeyList.Count - 1
                    If InitSettings.Instance.MailingList(i).OpenSslKeyList(j).PublicKey.Equals(strPublicKey) Then
                        Return New Integer(1) {i, j}
                    End If
                Next

                Return New Integer(1) {i, -1}
            End If
        Next

        Return Nothing

    End Function

    ''' <summary>
    ''' 自分メールに送信チェック
    ''' </summary>
    ''' <returns>チェック結果</returns>
    ''' <exception cref="Exception">チェック失敗</exception>
    Private Function checkSendMailToMyself() As Boolean
        Try
            '現時点の時間 - 変数「最終送信時間」 >= 設定ファイルの「自分メールに送信間隔」
            Dim dateNow As DateTime = DateTime.Now
            If dateNow >= lastSendTime.AddMinutes(settings.SendMailInterval) Then
                '変数「受信フラグ」＝「０」の場合、エラーイベントログ出力（出力メッセージ内容【エラー（未受信）】）。
                If flgReceipt = 0 Then
                    WriteToEventLog(ClsStatic.MSG_EVENTLOG.MAILSERVER_MYSELFSEND_ERR, ClsStatic.EventID.Err)
                ElseIf flgReceipt = 1 Then
                    '変数「受信フラグ」＝「１」の場合、イベントログ出力（出力メッセージ内容【正常（受信）】）。
                    WriteToEventLog(ClsStatic.MSG_EVENTLOG.MAILSERVER_MYSELFSEND_OK, ClsStatic.EventID.SuccessAudit)
                End If

                '■自分メールに送信
                If executeRetry(RetryItems.sendMailToMyself.name) = False Then Return False

                '変数の初期化
                '受信フラグを「０」にセット
                flgReceipt = 0
                '最終送信時間を現時点の時間にセット
                lastSendTime = dateNow
            End If

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return False
        End Try
    End Function
#End Region

#Region "CSVバックアップ処理"

    ''' <summary>
    ''' メールバックアップ処理
    ''' </summary>
    ''' <returns>処理結果</returns>
    ''' <exception cref="Exception">処理失敗</exception>
    Private Function writeCSV() As Boolean
        Const CST_DoubleQuotation As String = """"
        Dim strbText As String = ""
        Dim strbTitle As String = ""

        '↓ ADD AT 2014/01/23 BY SHIN (障害対応：CSV出力データ間のスペースを抜く)
        Const CST_Comma As String = ","
        '↑ ADD AT 2014/01/23 BY SHIN (障害対応：CSV出力データ間のスペースを抜く)

        Try

            strbTitle &= ClsStatic.INFO_OTHERS.ResultDecrypt
            strbText &= CST_DoubleQuotation & MailItemValue.resultDecrypt & CST_DoubleQuotation

            For i = 0 To MailItemValue.mailItems.Length - 1
                If MailItemValue.mailItems(i).outputLevel > 0 Then
                    'タイトル
                    If i = 0 Then
                        strbTitle &= CST_Comma & getValueBySeek(MailItemValue.mailItems(i).newItem, CST_Colon, False)
                    Else
                        strbTitle &= CST_Comma & MailItemValue.mailItems(i).newItem
                    End If
                    'データ
                    If i = MailItemValue.mailItems.Count - 1 Then
                        '暗号化キー項目の場合
                        strbText &= CST_Comma & CST_DoubleQuotation & getValueBySeek(MailItemValue.mailItems(i).value, CST_Equal) & CST_DoubleQuotation
                    Else
                        strbText &= CST_Comma & CST_DoubleQuotation & getValueBySeek(MailItemValue.mailItems(i).value, CST_Colon) & CST_DoubleQuotation
                    End If
                End If
            Next
            strbTitle &= CST_Comma & ClsStatic.INFO_OTHERS.MailBody
            strbText &= CST_Comma & CST_DoubleQuotation & MailItemValue.body & CST_DoubleQuotation

            Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
            Dim csvpath As String = path.csv & DateTime.Now.ToString("yyyyMMdd") + ".csv"

            Dim sr As System.IO.StreamWriter
            'CSVファイルにタイトルを書込み
            If Not System.IO.File.Exists(csvpath) Then
                sr = New System.IO.StreamWriter(csvpath, True, enc) '開く,書込み、追加
                sr.Write(strbTitle & vbCrLf)
            Else
                sr = New System.IO.StreamWriter(csvpath, True, enc) '開く,書込み、追加
            End If
            'CSVファイルに内容を書込み
            sr.Write(strbText & vbCrLf)
            sr.Close()
            sr.Dispose()
            sr = Nothing

            Return True
        Catch ex As Exception
            SystemError.SystemLog(ex.Message, "バックアップデータ：" & strbText)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' シークする文字列より、元文字列の一部を取得
    ''' </summary>
    ''' <param name="strValue">元文字列</param>
    ''' <param name="strSeek">シークする文字列</param>
    ''' <param name="isEnd">後の文字列を取得するか</param>
    ''' <returns>元文字列の一部</returns>
    ''' <remarks></remarks>
    Private Function getValueBySeek(ByVal strValue As String, ByVal strSeek As String, _
                                    Optional ByVal isEnd As Boolean = True) As String
        If String.IsNullOrEmpty(strValue) Then Return String.Empty

        Dim retValue As String = strValue
        Try
            Dim index As Integer = strValue.IndexOf(strSeek)
            If index >= 0 Then
                If isEnd Then
                    retValue = strValue.Substring(index + strSeek.Length)
                Else
                    retValue = strValue.Substring(0, index)
                End If
            End If

            Return retValue.Trim
        Catch ex As Exception
            SystemError.SystemLog(ex)
            Return Nothing
        End Try
    End Function
#End Region

#Region "イベントログ出力"

    ''' <summary>
    ''' イベントログ出力
    ''' </summary>
    ''' <param name="Entry">エントリで書き込むメッセージ内容</param>
    ''' <param name="EventID"></param>
    ''' <param name="AppName">イベント・ソース名。イベント・ソースはほとんどの場合、アプリケーション名を指す。</param>
    ''' <param name="EventType">EventLogEntryType列挙体。メンバ説明：
    ''' 　　　　　　　　Information　情報。成功した操作を示す
    ''' 　　　　　　　　Warning　　　警告。今後問題の原因となり得る問題を示す
    ''' 　　　　　　　　Error　　　　エラー。ユーザーに知らせる必要がある重大な問題を示す
    ''' 　　　　　　　　SuccessAudit 成功した監査。監査アクセスに成功したこと（例えば、ログオンに成功したなど）を示す
    ''' 　　　　　　　　FailureAudit 監査エラー。監査アクセスに失敗したこと（ファイルを開けなかったなど）を示す
    ''' </param>
    ''' <param name="LogName">イベント・ログ名例では
    ''' 　　　　　　　「アプリケーション」
    '''               「Internet Explorer」
    '''               「Microsoft Office Diagnostics」
    '''               「Microsoft Office Sessions」
    '''               「セキュリティ」
    '''               「システム」
    '''               「Windows PowerShell」などの種類がある。
    ''' </param>
    ''' <returns>EventLog書き込み結果</returns>
    ''' <remarks></remarks>
    Public Function WriteToEventLog(ByVal Entry As String, _
      Optional ByVal EventID As Integer = 0, _
      Optional ByVal AppName As String = "FeedService", _
      Optional ByVal EventType As  _
      EventLogEntryType = EventLogEntryType.Information, _
      Optional ByVal LogName As String = "Application") As Boolean

        Dim objEventLog As New EventLog()
        'ローカル・コンピュータの場合は「.」と記述すればよい。
        Dim cpt = "."             ' コンピュータ名
        Try
            'SourceExistsメソッドは、第1引数にイベント・ソース名、
            '第2引数にコンピュータ名を指定する（ローカル・コンピュータの場合は、
            '第2引数は指定しなくてもよい）。
            '戻り値がtrueの場合はそのイベント・ソースは存在し、falseの場合は存在しない。
            If Not Diagnostics.EventLog.SourceExists(AppName, cpt) Then
                Diagnostics.EventLog.CreateEventSource(AppName, LogName)
            End If
            objEventLog.Source = AppName

            Select Case EventID
                Case ClsStatic.EventID.SuccessAudit
                    EventType = EventLogEntryType.SuccessAudit
                Case ClsStatic.EventID.Warning
                    EventType = EventLogEntryType.Warning
                Case ClsStatic.EventID.Err
                    EventType = EventLogEntryType.Error
                Case Else
                    EventType = EventLogEntryType.Information
            End Select
            objEventLog.WriteEntry(Entry, EventType, EventID)

            'エラーログを出力
            If EventID <> ClsStatic.EventID.SuccessAudit Then SystemError.SystemLog(Entry)

            Return True
        Catch Ex As Exception
            Return False
        End Try
        objEventLog.Dispose()
    End Function

#End Region

End Class
